/**
 * HSI-88.h
 *
 * HSI-88 Fast S88 PC Interface 
 * 
 * This software emulates the HSI-88 from Littfinski. It has three S88 busses that it activly scans only reporting the changed
 * signals to the PC.
 *
 * Author:   Elze Kool <efrkool@live.nl>
 * Date:     27-nov-2009
 * Software: AVR-GCC
 * Target:   AT90USB162 @ 8Mhz on the Olimex AVR-USB-162 development board
 *
 * Based on the LUFA USB Library and Serial CDC Example:
 * Parts Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)
 *
 */

/** \file
 * Descriptor file for HSI-88.c
 **/
 
#ifndef _HSI_88_H_
#define _HSI_88_H_

	// Number of registers 
	#define NUM_REGISTERS 3

	// EEPROM adres of first register
	#define REGISTER_FIRST 10
	
	// Register that controls CR+LF option in terminal mode
	#define REGISTER_CRLF_OPTION 0
	
	// Register that controls number of cycles to wait after asserting LOAD_DATA / RESET
	#define REGISTER_LOAD_DATA_WAIT 1
	
	// Register that controls the speed of the clock
	#define REGISTER_CLK_SPEED 2
	
	// Register that allows enabling/disabling of virtual connector
	#define REGISTER_ENABLE_VIRTUAL 3
	
	
	
	// Define maximum number of modules per line
	#define MAX_NUMBER_OF_MODULES 10
	
	// EVENT_USB_Device_UnhandledControlRequest defines
	#define REQ_GetLineEncoding          0x21
	#define REQ_SetLineEncoding          0x20
	#define REQ_SetControlLineState      0x22

	// Notify new Signal State 
	#define NOTIF_SerialState            0x20

	// DTR Signal
	#define CONTROL_LINE_OUT_DTR         (1 << 0)


	// Port adresses for LEDs
	#define PORT_LED	PORTD
	#define DDR_LED		DDRD
	
	// Pin masks for LEDs
	#define PIN_LED_RED		(1 << PD4)
	#define PIN_LED_GREEN	(1 << PD0)
	#define PIN_LED_YELLOW	(1 << PD2)
	
	// Port adresses for S88 Bus
	#define PORT_S88 	PORTC
	#define PIN_S88		PINC
	#define DDR_S88		DDRC
	
	// Pin masks for S88 Bus
	#define PIN_DATA1 (1 << PC6)
	#define PIN_DATA2 (1 << PC7)
	#define PIN_DATA3 (1 << PC1)	
	#define PIN_CLOCK (1 << PC2)	
	#define PIN_LOAD  (1 << PC4)
	#define PIN_RESET (1 << PC5)
	
	// Mask of PORTD pins used for virtual connector
	#define MASK_VIRTUAL 0x6F
	#define MASK_N_VIRTUAL ~(MASK_VIRTUAL)
	
	
	/**
	 *  Type define for the virtual serial port line encoding settings, for storing the current USART configuration
	 *  as set by the host via a class specific request.
	 **/
	typedef struct
	{
		/**
		 * Baud rate of the virtual serial port, in bits per second
		 **/
		uint32_t BaudRateBPS;  
		
		/**
		 * Character format of the virtual serial port, a value from the
		 * CDCDevice_CDC_LineCodingFormats_t enum
		 **/
		char  CharFormat; 

		/**
		 * Parity setting of the virtual serial port, a value from the
		 * CDCDevice_LineCodingParity_t enum
		 **/
		char  ParityType; 
		
		/**
		 * Bits of data per character of the virtual serial port 
		 */
		char  DataBits; 
		
	} CDC_Line_Coding_t;
		
		
	/** 
	 * Type define for a CDC notification, sent to the host via the CDC notification endpoint to indicate a
	 * change in the device state asynchronously.
	 */
	typedef struct
	{
		/**
		 *  Notification type, a mask of REQDIR_*, REQTYPE_* and REQREC_* constants
		 *  from the library StdRequestType.h header
		 */
		uint8_t  NotificationType; 
		
		/** 
		 * Notification value, a NOTIF_* constant 
		 */
		uint8_t  Notification; 
		
		/** 
		 * Notification wValue, notification-specific 
		 */		
		uint16_t wValue; 
		
		/**< Notification wIndex, notification-specific */
		uint16_t wIndex; 
		
		/**< Notification wLength, notification-specific */
		uint16_t wLength; 
	} USB_Notification_Header_t;
		

	/** 
	 * Enum for the possible line encoding formats of a virtual serial port. 
	 **/
	enum CDCDevice_CDC_LineCodingFormats_t
	{
		/**
		 * Each frame contains one stop bit 
		 **/
		OneStopBit          = 0, 
		
		/**
		 * Each frame contains one and a half stop bits
		 **/
		OneAndAHalfStopBits = 1, 
		
		/**
		 * Each frame contains two stop bits
		 **/
		TwoStopBits         = 2, 
	};
		
	/** 
	 * Enum for the possible line encoding parity settings of a virtual serial port. 
	 **/
	enum CDCDevice_LineCodingParity_t
	{
		/**
		 * No parity bit mode on each frame
		 **/
		Parity_None         = 0, 

		/**
		 * Odd parity bit mode on each frame
		 **/
		Parity_Odd          = 1, 
		
		/**
		 * Even parity bit mode on each frame
		 **/
		Parity_Even         = 2,
		
		/**
		 * Mark parity bit mode on each frame
		 **/
		Parity_Mark         = 3, 
		
		/**
		 * Space parity bit mode on each frame
		 **/
		Parity_Space        = 4, 
	};
		


	// Setup hardware
	void SetupHardware(void);

	// USB Device 
	void EVENT_USB_Device_Connect(void);
	void EVENT_USB_Device_Disconnect(void);
	void EVENT_USB_Device_ConfigurationChanged(void);
	void EVENT_USB_Device_UnhandledControlRequest(void);

	// Tasks
	void TASK_USB_SEND_RECIEVE(void);
	void TASK_READ_S88(void);
	void TASK_PC_COMM(void);
	
	// Character/Text functions
	void SendS88Status(uint8_t module_number);		
	void UART_sendbyte(uint8_t x);
	uint8_t HexToByte(uint8_t high_nibble, uint8_t  low_nibble);	
	
	int UART_sendchar(char c, FILE *stream);
	bool UART_havedata(void);
	
	// EEPROM functions
	void WriteRegister(uint16_t address, uint8_t value);
	uint8_t ReadRegister(uint16_t address);
	
#endif

/** 
 * END of HSI-88.h
 **/